/**
 * 将路由代码封装到一个单独的组件
 */
import React from "react";
import { HashRouter, Route, Redirect, Switch } from "react-router-dom";
//引进路由页面组件
import About from "../views/About";
import Home from "../views/Home";
import NotFound from "../views/NotFound";

export default function IndexRouter() {
    return (
        //  HashRouter模式路由前面带#号*（hash模式），BrowserRouter模式路由前面不带#
        <HashRouter>
            {/* Switch的作用是只渲染匹配到的第一个，匹配完了直接跳出，不执行后面的，
            从而解决Redirect模糊匹配的问题和多个路由被匹配从而被同时渲染的问题  */}
            <Switch>
                {/* <Route></Route>组件会向它component内的组件传递一个props对象，里面包含可以进行路由跳转，获取参数等操作，见下方Route源码 */}
                {/* path路由地址 component对应页面组件 */}
                <Route path='/home' component={Home} />

                {/* 使用Switch时在访问/home/a不会展示这里的Home1组件而是会展示上面/home对应的Home组件，
                因为react路由是《模糊匹配》，以上面的/home为例，因为它在代码前面（路由匹配顺序是从上到下），
                所以以/home开头的路由都会先被匹配到Home组件，代码后面的/home开头的路由就不会再匹配，
                而不使用Switch时，访问/home/a，则Home组件和Home1组件都会被渲染到页面上，
                除非在上面/home的路由上加上exact关键字使它变成精准匹配，才能在访问/home/a时保证不显示Home组件，
                为了提高代码的可读性和避免不必要的麻烦，像这种情况一般使用嵌套路由而不是直接使用二级路由 */}
                {/* <Route path='/home/a' component={Home1} /> */}

                <Route path='/about' component={About} />

                {/* Redirect重定向组件，从from重定向到to，但是这个from也是模糊匹配，这里写的效果是以/开头的都会被匹配
                运行案例查看效果会发现第一次进入到about路由正常渲染about页面，
                但一旦当页面刷新会被Redirect捕捉重定向到home页面，解决该问题可使用router的Switch组件，
                或加上exact关键字使Redirect变成精准匹配（Redirect即使使用了exact外面还要嵌套Switch来用）
            */}
                <Redirect from='/' to='/home' exact />

                {/* path设置为*或干脆不加path属性，会匹配业务路由匹配不到的所有路由，常做404页面路由使用 */}
                {/* 需要注意的是使用它时，如果还使用了Redirect，Redirect一定要加exact，不然一些未被业务路由匹配
                的路由可能会被Redirect先匹配而不是被它所匹配 */}
                <Route path='*' component={NotFound} />
            </Switch>
        </HashRouter>
    );
}

// Route部分源码
// class Route extends Component {
//     // ...
//     render() {
//         var MyComponent = this.props.component;
//         return (
//             <div>
//                 {/* ... */}
//                 <MyComponent history={} match={} .../>
//             </div>
//         );
//     }
// }
// Route组件接收到component属性后，会在自己内部创建这个属性子组件并向其传了history、match等props
